package com.csaba.connector.axa.model;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;

import com.csaba.connector.axa.AXAAccountHistoryService;
import com.csaba.connector.axa.AXAAccountLoginService;
import com.csaba.connector.axa.AXAAccountService;
import com.csaba.connector.axa.AXALoginService;
import com.csaba.connector.axa.AXALogoutService;
import com.csaba.connector.axa.AXASMSOTPValidationService;
import com.csaba.connector.axa.AXASelectAccountService;
import com.csaba.connector.axa.Codes;
import com.csaba.connector.model.Account;
import com.csaba.connector.model.Customer;
import com.csaba.connector.model.HistoryItem;
import com.csaba.connector.model.Session;
import com.csaba.connector.service.AccountHistoryService;
import com.csaba.connector.service.AccountService;
import com.csaba.connector.service.LoginService;
import com.csaba.connector.web.util.SpecialHttpClient;
import com.csaba.connector.web.util.WebSession;
import com.csaba.util.LoggerHelper;

public class AXASession extends WebSession implements Codes
{
	private static final long serialVersionUID = 682449734086603277L;

	private final static Logger logger = LoggerHelper.getDefaultLogger();

	public static final boolean DEBUG_COOKIES = false;
	public final static boolean DUMP_TEXT = false;
	public final static boolean DEBUG_FILE = false;
	public final static String DEBUG_FILE_PATH = "../axa.source/";
	public final static int DUMMY_FREQUENCY = 5 * 60; //sec
	public final static String COOKIE_SESSIONID = "ASP.NET_SessionId";

	private final static String BASE_URL = "https://ibanq.axabank.hu";

	public AXASession()
	{
		super();
		setBank(AXABank.getInstance());
		if ( DEBUG_FILE )
			setDebugFilePath(DEBUG_FILE_PATH);
		setDumpText(DUMP_TEXT);
		setDebugCookies(DEBUG_COOKIES);
		setDummyInterval(DUMMY_FREQUENCY);

		setRedirectHandler(new RedirectHandler()
		{

			@Override
			public String redirectedTo( final String url )
			{
				if ( url.startsWith("http") )
					return url;
				return BASE_URL + url;
			}
		});

		//set language based on the default locale
		final Locale defaultLocale = Locale.getDefault();
		String language = LANGUAGE_ENGLISH;
		if ( "hu".equalsIgnoreCase(defaultLocale.getLanguage()) )
			language = LANGUAGE_HUNGARIAN;
		setRemoteProperty(RP_LANGUAGE, language);
		//FIXME set language with cookie (IBL=hun; expires=Sat, 10-Sep-2011 19:41:37 GMT; path=/)
		// language is set as remoteproperty RP_LANGUAGE
	}

	@Override
	protected DefaultHttpClient initHttpClient()
	{
		return new SpecialHttpClient(SpecialHttpClient.CERT_NETLOCK_ARANY_B);
	}

	@Override
	protected void detectSessionCookie()
	{
		final List<Cookie> cookies = client.getCookieStore().getCookies();
		for ( final Cookie cookie : cookies )
		{
			if ( cookie.getName().equals(COOKIE_SESSIONID) )
			{
				final String sessionId = cookie.getValue();
				if ( getSessionId() != null && !getSessionId().equals(sessionId) )
				{
					logger.severe("Session ID is changed from " + getSessionId() + " to " + sessionId);
				}
				setSessionId(sessionId);
			}
		}
	}

	public static String getRequestURL( final String requestId )
	{
		return BASE_URL + requestId;
	}

	public static void main( final String[] args ) throws Exception
	{
		LoggerHelper.initLogger(Level.FINEST);

		//login service
		final Customer customer = new Customer();
		customer.setLoginId(args[0]);
		customer.setPassword(args[1]);

		final LoginService login = new AXALoginService();
		login.setCustomer(customer);

		login.execute(null);

		final Session session = login.getSession();
		//SMS is posted to the phone
		try
		{

			//get OTP
			final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			String otp = null;
			while ( !( otp = reader.readLine() ).startsWith("otp") )
			{
				if ( otp.equals("stop") )
					return;
			}
			;

			otp = otp.substring(3);

			final AXASMSOTPValidationService otpValidation = new AXASMSOTPValidationService();
			otpValidation.setSmsotp(otp);

			otpValidation.execute(session);

			final Account[] accounts = (Account[]) session.getRemoteProperty(RP_ACCOUNT_LIST);
			for ( final Account account : accounts )
			{
				System.out.println("Account: " + account);
			}

			//select account
			final AXASelectAccountService selectAccount = new AXASelectAccountService();
			selectAccount.setAccount(accounts[0]);

			selectAccount.execute(session);

			final int[] pinMask = selectAccount.getPinMask();

			final String pin = args[2];
			final char[] pins = new char[] { '*', '*', '*', '*', '*', '*', };
			System.out.print("PIN Mask: ");
			for ( final int i : pinMask )
			{
				System.out.print(i + " ");
				pins[i] = pin.charAt(i);
			}
			System.out.println();

			//account login
			final AXAAccountLoginService accountLogin = new AXAAccountLoginService();
			accountLogin.setPinDigits(pins);

			accountLogin.execute(session);

			System.out.println("Login was succesful.");

			//get account
			final AccountService accountService = new AXAAccountService();

			accountService.execute(session);

			final Account[] accBalances = accountService.getAccounts();
			for ( final Account account : accBalances )
			{
				System.out.println("account: " + account.getNumber() + " => " + account.getBookedBalance() + "; "
						+ account.getAvailableBalance());
			}

			//get transactions
			final AccountHistoryService accountHistory = new AXAAccountHistoryService();

			final Calendar today = Calendar.getInstance();
			final Date to = today.getTime();
			today.add(Calendar.DATE, 0);
			final Date from = today.getTime();
			accountHistory.setDateRange(from, to);
			accountHistory.setAccount((Account) session.getRemoteProperty(RP_SELECTED_ACCOUNT));
			accountHistory.execute(session);

			final HistoryItem[] historyItems = accountHistory.getHistory();
			for ( final HistoryItem historyItem : historyItems )
			{
				System.out.println("History: " + historyItem);
			}
		}
		finally
		{
			//logout
			( new AXALogoutService() ).execute(session);
		}
	}
}
